<?php
/**
 * 导入导出存储方式调用统一入口
 */
class importexport_policy
{

    /**
     * 提供导入导出的存储方式
     *
     * @return array $storage 返回存储方式的参数
     */
    public function storage_policy(){

        $storage = array(
            #storage支持类型为ftp
            'policy' => 'ftp',

            #后台导入导出存储方式配置页面
            'view' => array('html'=>'admin/ftp.html','app'=>'importexport'),

            #setConf存储配置信息的key
            'setting_key' => 'ftp_server_setting',

            //是否需要配置参数
            'is_store_params' => true,

            #存储服务器配置view页面 调用的其他参数
            'params' => array(
                'support_ftp'=> extension_loaded('ftp'),//php是否支持ftp扩展
            ),
            //配置参数变量定义
            'var_server_params' => 'ftp_server',
        );

        return $storage;
    }

    /**
     * 保存存储方式的配置参数 如果需要配置则存储配置
     *
     * @params array $params
     * @return bool
     */
    public function set_storage_params($params){
        $storage = $this->storage_policy();
        if( $storage['is_store_params'] ){
            $flag = app::get('importexport')->setConf($storage['setting_key'],$params);
        }else{
            $flag = true;
        }
        return $flag ? true : false;
    }

    /**
     * 获取存储方式的配置参数
     *
     * @return array $params
     */
    public function get_storage_params(){
        $storage = $this->storage_policy();
        if( $storage['is_store_params'] ){
            $params = app::get('importexport')->getConf($storage['setting_key']);
        }else{
            $params = true;
        }
        return $params;
    }

    /**
     * 获取到导入导出存储调用类,并建立连接
     *
     */
    public function connect(){
        $this->_instance();
        $params = $this->get_storage_params();
        if( !$params ) return false;

        if ( !$this->policy_obj->connect($params,$msg) )
        {
            return $msg;
        }

        return true;
    }

    /**
     * 实例化存储方式类
     */
    private function _instance(){
        $params = $this->storage_policy();
        $obj_name = 'importexport_policy_'.$params['policy'];
        $this->policy_obj = kernel::single($obj_name);
        return true;
    }

    /**
     * 检查配置信息是否成功
     */
    public function check(){
        $this->_instance();

        $params = $this->get_storage_params();

        return $this->policy_obj->check($params);
    }


    /**
     * 将本地生成的文件push到远程服务器
     *
     * @params array $params 参数 array('local'=>'本地文件路径','remote'=>'远程文件路径','resume'=>'文件指针位置')
     * @return bool
     */
    public function push($params){

        $params['local'] = $params['local'] ? $params['local'] : $this->local_file;
        $params['remote'] = $params['remote'] ? $params['remote'] : $this->remote_file;
        $params['resume'] = $params['resume'] ? $params['resume'] : $this->ftell;

        if( empty($params['local']) || empty($params['remote']) )
        {
            logger::info('文件上传失败 文件名称参数错误 => '.var_export($params,1));
            return false;
        }

        if ( !$this->policy_obj->push($params,$msg) )
        {
            logger::info('文件上传失败 =>'.$msg );
            return false;
        }
        return true;
    }

    /**
     * 将本地生成的文件push到远程服务器
     *
     * @params array $params 参数 array('local'=>'本地文件路径','remote'=>'远程文件路径','resume'=>'文件指针位置')
     * @params string $msg   错误信息传引用
     * @return bool
     */
    public function pull($params,&$msg){
        $params['local'] = $params['local'] ? $params['local'] : $this->local_file;
        $params['remote'] = $params['remote'] ? $params['remote'] : $this->remote_file;
        $params['resume'] = $params['resume'] ? $params['resume'] : $this->ftell;

        if( empty($params['local']) || empty($params['remote']) )
        {
            logger::info('文件上传失败 文件名称参数错误 => '.var_export($params,1));
            return false;
        }
        if ( !$this->policy_obj->pull($params,$msg) )
        {
            logger::info('文件下载失败 =>'.$msg );
            return false;
        }
        return true;
    }

    /**
     * 获取文件大小
     */
    public function remote_file_size($filename){
        return $this->policy_obj->size($filename);
    }

    //删除存储服务器文件
    public function delete_remote_file($filename=null){
        $filename = $filename ? $filename : $this->remote_file;
        $this->policy_obj->delete($filename);
        return true;
    }

    /**
     * 创建本地临时文件,用于上传，下载的临时文件
     *
     * @return resource $file 返回文件句柄
     */
    public function create_local_file(){
        $this->local_file = tempnam(TMP_DIR,'importexport');
        if(!$this->local_file)
        {
            return false;
        }
        $this->file = fopen($this->local_file,'w');
        return $this->file;
    }

    /**
     * 创建远程文件名称
     *
     * @params array array('key'=>"远程文件名称",'filetype'=>'远程文件类型')
     */
    public function create_remote_file($params){
        $this->remote_file =  $params['key'].'.'.$params['filetype'];
        return $this->remote_file;
    }

    /**
     * 写入本地临时文件,用于上传，下载的临时文件
     *
     * @return bool 返回成功则返回true，失败返回false
     */
    public function write_local_file($rs){
        $this->ftell = ftell($this->file);
        if( !fwrite($this->file, $rs) )
        {
            return false;
        }
        return true;
    }

    /**
     * 获取到本地文件大小
     *
     * @params bool $is_format  是否需要格式化文件大小数据
     */
    public function size_local_file($is_format=false){
        $filesize = filesize($this->local_file);

        if(!$is_format){
            return $filesize;
        }

        $bytes = floatval($filesize);
        switch($bytes)
        {
            case $bytes< 1024:
                $result = $bytes.'B';
                break;
            case ($bytes < pow(1024, 2) ):
                $result =  strval(round($bytes/1024, 2)).'KB';
                break;
            default:
                $result = $bytes/pow(1024, 2);
                $result = strval(round($result, 2)).'MB';
                break;
        }
        return $result;
    }

    /**
     * 关闭,删除 本地临时文件
     *
     * @return bool 返回成功则返回true，失败返回false
     */
    public function close_local_file($file=null){
        if(!$file) $file = $this->file;
        fclose($file);
        unlink($this->local_file);
        return true;
    }
}
